package com.le.medium.class4;

import org.junit.Test;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

/**
 * 如何仅用队列结构实现栈结构?
 * 如何仅用栈结构实现队列结构?
 */
public class Problem03_StackAndQueueConvert {

    // 队列实现栈
    public static class TwoQueuesStack{
        private Queue<Integer> queuePush;
        private Queue<Integer> help;

        public TwoQueuesStack() {
            this.queuePush = new LinkedList<>();
            this.help = new LinkedList<>();
        }

        public void push(Integer val){
            this.queuePush.offer(val);
        }

        public int pop(){
            while (this.queuePush.size() != 1){
                this.help.offer(this.queuePush.poll());
            }
            int val = this.queuePush.poll();
            swap();
            return val;
        }

        public int getPeek(){
            while (this.queuePush.size() != 1){
                this.help.offer(this.queuePush.poll());
            }
            int res = this.queuePush.poll();
            this.help.offer(res);
            swap();
            return res;
        }

        public void swap(){
            Queue<Integer> temp = this.queuePush;
            this.queuePush = this.help;
            this.help = temp;
        }



        @Test
        public void test(){
            TwoQueuesStack queue = new TwoQueuesStack();
            queue.push(1);
            queue.push(2);
            queue.push(3);
            queue.push(4);
            System.out.println(queue.pop());
            System.out.println(queue.getPeek());
        }
    }

    // 栈实现队列
    public static class TwoStacksQueue{
        private Stack<Integer> stackPush;
        private Stack<Integer> stackPop;

        public TwoStacksQueue() {
            this.stackPush = new Stack<Integer>();
            this.stackPop = new Stack<Integer>();
        }

        public void push(int pushInt) {
            stackPush.push(pushInt);
        }

        public int pop(){
           if (this.stackPush.isEmpty() && this.stackPop.isEmpty()){
               throw new RuntimeException();
           }else if (this.stackPop.isEmpty()){
               while (!this.stackPush.isEmpty()){
                   this.stackPop.push(this.stackPush.pop());
               }
           }
           return this.stackPop.pop();
        }

        public int peek() {
            if (stackPop.empty() && stackPush.empty()) {
                throw new RuntimeException("Queue is empty!");
            } else if (stackPop.empty()) {
                while (!stackPush.empty()) {
                    stackPop.push(stackPush.pop());
                }
            }
            return stackPop.peek();
        }
    }
}
